<template>
  <div class="content-box">
    <div class="search-box">
      <el-select
        v-model="keywords"
        filterable
        remote
        reserve-keyword
        placeholder="请输入关键词"
        :remote-method="remoteMethod"
        :loading="loading"
        :clearable="true"
        style="width: 360px"
        size="default"
        :disabled="disabled"
        @change="changeSelect"
      >
        <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item" class="one-text">
          <span style="float: left">{{ item.name }}</span>
          <span style="float: right; color: #8492a6; font-size: 13px">{{ item.district }}</span>
        </el-option>
      </el-select>
    </div>
    <div id="map-box" :style="'height:' + height + 'px;'"></div>
  </div>
</template>

<script setup lang="ts" name="AMap">
import { onMounted, reactive, ref, watch } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";
import { ElMessage } from "element-plus";

/*window._AMapSecurityConfig = {
  securityJsCode: "" // '「申请的安全密钥」',
};*/

const props = defineProps({
  disabled: {
    type: Boolean,
    default: () => true
  },
  height: {
    type: Number,
    default: () => 200
  },
  style: {
    type: String,
    default: () => "amap://styles/macaron"
  },
  lng: {
    type: Number,
    default: () => 113.370824
  },
  lat: {
    type: Number,
    default: () => 23.131265
  }
});

const emits = defineEmits(["changePosition"]);

const disabled = ref(props.disabled);
const keywords = ref("");
const loading = ref(false);
const options = ref<any[]>([]);

const state = reactive<any>({
  center: [props.lng, props.lat], // 地图中心点
  position: [props.lng, props.lat], // 经纬度-lng lat
  style: props.style, // 地图颜色底层
  map: null, // 地图实例
  icon: null, // 标记icon
  marker: null, // 地图标记
  geocoder: null, // 逆解析实例
  autocomplete: null
});

onMounted(() => {
  initAMap();
});

watch(
  () => props.disabled,
  newVal => {
    disabled.value = newVal;
  }
);

watch(
  () => [props.lng, props.lat],
  (newVal: number[]) => {
    state.position = [newVal[0], newVal[1]];
    state.center = state.position;
    if (state.map) {
      state.map.setCenter(state.position);
    }
    if (state.marker) {
      state.marker.setPosition(state.position);
    }
  }
);

const initAMap = async () => {
  AMapLoader.load({
    key: "9182bee9e21c259536168273effe32dc", // 申请好的Web端开发者Key，首次调用 load 时必填
    version: "2.0", // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
    plugins: ["AMap.Scale", "AMap.Geocoder", "AMap.Marker", "AMap.CitySearch", "AMap.Geolocation", "AMap.AutoComplete"] // 需要使用的的插件列表，如比例尺'AMap.Scale'等
  })
    .then(AMap => {
      // 获取到作为地图容器的DOM元素，创建地图实例
      state.map = new AMap.Map("map-box", {
        //设置地图容器id
        resizeEnable: true, // 是否监控地图容器尺寸变化
        viewMode: "3D", // 使用3D视图
        zoomEnable: true, // 地图是否可缩放，默认值为true
        dragEnable: true, // 地图是否可通过鼠标拖拽平移，默认为true
        doubleClickZoom: true, // 地图是否可通过双击鼠标放大地图，默认为true
        zoom: 12, // 初始化地图级别
        center: state.center, // 初始化中心点坐标 广州
        mapStyle: state.style // 设置颜色底层
      });
      // 设置icon
      state.icon = new AMap.Icon({
        size: new AMap.Size(19, 33),
        image: "/mark_bs.png"
      });
      // 添加标记点
      state.marker = new AMap.Marker({
        icon: state.icon,
        position: state.position,
        offset: new AMap.Pixel(-13, -30), // icon中心点的偏移量
        draggable: false, // 设置是否可拖拽
        // cursor: "move",
        animation: "AMAP_ANIMATION_BOUNCE"
      });
      state.marker.setMap(state.map);
      // 监听用户的点击事件
      state.map.on("click", (e: any) => {
        // 调用逆解析方法 个人开发者调用量上限5000（次/日）
        state.geocoder.getAddress(e.lnglat, function (status: any, result: any) {
          if (status === "complete" && result.regeocode) {
            keywords.value =
              result.regeocode.aois.length > 0 ? result.regeocode.aois[0]?.name : result.regeocode.formattedAddress;
            emits("changePosition", result.regeocode.formattedAddress, e.lnglat);
          } else {
            ElMessage.error("根据地址查询位置失败，请重新选择！");
          }
        });
      });
      // 地址逆解析插件。
      state.geocoder = new AMap.Geocoder({
        city: "全国", // 地理编码时，设置地址描述所在城市; 默认全国; 可选值：城市名（中文或中文全拼）、citycode、adcode
        radius: 1000, // 逆地理编码时，以给定坐标为中心点; 默认1000; 取值范围(0-3000)
        extensions: "all" // 逆地理编码时，返回信息的详略; 默认值：base，返回基本地址信息; 默认值：base，返回基本地址信息
      });
      // 搜索提示插件
      state.autocomplete = new AMap.AutoComplete({ city: "全国" });
    })
    .catch(e => {
      console.log(e);
    });
};

// 搜索
const remoteMethod = (query: string) => {
  if (query === "") {
    options.value = [];
    return;
  }
  loading.value = true;
  setTimeout(() => {
    loading.value = false;
    state.autocomplete.search(query, (status: any, result: any) => {
      options.value = result.tips;
    });
  }, 200);
};

// 选中下拉地址项
const changeSelect = addr => {
  keywords.value = addr.name;
  if (addr.location) {
    emits("changePosition", addr.district + addr.address, addr.location);
  }
};
</script>

<style scoped lang="scss">
.content-box {
  position: relative;
  width: 100%;
  .search-box {
    position: absolute;
    z-index: 1;
    top: 5px;
    left: 5px;
  }
  #map-box {
    width: 100%;
    height: 100%;
    margin: 0;
  }
}
</style>
